#!/usr/bin/env python
# -*- coding: utf-8 -*-
##
#   Project: gmediacatalog - Catalog your media to find them later
#    Author: Fabio Castelli <muflone@vbsimple.net>
# Copyright: 2010 Fabio Castelli
#   License: GPL-2+
#  This program is free software; you can redistribute it and/or modify it
#  under the terms of the GNU General Public License as published by the Free
#  Software Foundation; either version 2 of the License, or (at your option)
#  any later version.
# 
#  This program is distributed in the hope that it will be useful, but WITHOUT
#  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
#  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
#  more details.
# 
# On Debian GNU/Linux systems, the full text of the GNU General Public License
# can be found in the file /usr/share/common-licenses/GPL-2.
##


import os
import signal
import sys

import gtk
import gobject
import gio

import preferences
import handlepaths
import plugins
import sqlbackend
from scanfolders import ScanFolders
from giodevices import GIODevices
from macros import *
from constants import *


class ScanVolume(object):
  def __init__(self, connection, ppid):
    self.scan = None
    self.connection = connection
    self.ppid = ppid        # Used to signal parent process upon closing
    self.timeoutProgress = None

    builder = gtk.Builder()
    builder.add_from_file(handlepaths.get_path('ui', 'addVolume.glade'))
    builder.connect_signals({
      'on_winScan_delete_event': self.on_winScan_delete_event,
      'on_actionCancel_activate': self.on_actionCancel_activate,
      'on_actionScan_activate': self.on_actionScan_activate,
      'on_txtVolumeName_focus_out_event': self.on_txtVolumeName_focus_out_event
    })
    gw = builder.get_object

    self.winScan = gw('winScan')
    self.actionScan = gw('actionScan')
    self.filePath = gw('filePath')
    self.txtVolumeName = gw('txtVolumeName')
    self.txtVolumeDescription = gw('txtVolumeDescription')
    self.lblCurrent = gw('lblCurrent')
    self.progressScan = gw('progressScan')
    self.chkSkipGvfs = gw('chkSkipGvfs')

    self.txtVolumeName.set_activates_default(True)
    self.txtVolumeDescription.set_activates_default(True)
    
    self.winScan.set_icon_from_file(handlepaths.get_app_logo())
    self.winScan.set_default_size(400, 200)
    self.winScan.set_title('%s - Add new catalog' % APP_TITLE)

  def run(self):
    self.progressScan.set_fraction(0.0)
    self.winScan.show()
    gtk.main()

  def update_progress(self):
    "Update progressbar"
    if self.scan:
      self.lblCurrent.set_label(self.scan.scanningPath)
    gtk_process_events()
    if self.timeoutProgress:
      self.progressScan.pulse()
      return True
    else:
      return False

  def on_actionScan_activate(self, widget, data=None):
    "Scan the selected device/folder"
    if self.txtVolumeName.get_text().strip():
      plugins.signal_proxy('on_before_new_volume')
      self.enable_disable_widgets(False)
      self.timeoutProgress = gobject.timeout_add(100, self.update_progress)
      self.scan = ScanFolders(self.connection)
      self.scan.skip_gvfs = self.chkSkipGvfs.get_active()
      
      name = self.txtVolumeName.get_text()
      description = self.txtVolumeDescription.get_text()
      fVolume = gio.File(self.filePath.get_uri())
      plugins.signal_proxy('on_new_volume', 
        argc=3, args=(name, description, fVolume))
      volume_id = self.scan.scan_volume(
        name, description, fVolume.get_uri(), 0, 0)
      plugins.signal_proxy('on_after_new_volume', argc=1, args=volume_id)
      # Stop further progress pulsations and clear timeout
      self.timeoutProgress = None
      # Clear volume name
      self.txtVolumeName.set_text('')
      self.on_txtVolumeName_focus_out_event(widget, None, data)
      # Scan completed or cancelled
      if self.scan:
        self.progressScan.set_fraction(1.0)
        self.lblCurrent.set_label('Volume scan completed')
      else:
        self.progressScan.set_fraction(0.0)
        self.lblCurrent.set_label('Volume scan cancelled')
      # Ready to start again
      self.scan = None
      self.enable_disable_widgets(True)
      self.txtVolumeName.set_property('secondary_icon_stock', None)

  def on_actionCancel_activate(self, widget, data=None):
    "Cancel running scan"
    print 'chiudi'
    if self.scan:
      # Cancel running scan
      self.scan.cancel_scan()
      self.scan = None
      self.enable_disable_widgets(True)
    else:
      # Close window and application
      self.winScan.destroy()
      self.on_winScan_delete_event(None, data)

  def on_winScan_delete_event(self, event, data=None):
    # Cancel running scan before terminate
    if self.scan:
      self.on_actionCancel.activate()
      return True
    # Was provided a parent pid? then signal it to enable again
    if self.ppid:
      os.kill(self.ppid, signal.SIGUSR1)
    gtk.main_quit()
    return False

  def on_txtVolumeName_focus_out_event(self, widget, event, data=None):
    "Check for missing volume name"
    self.txtVolumeName.set_property('secondary_icon_stock', 
      not self.txtVolumeName.get_text().strip() and \
      'gtk-dialog-warning' or None)

  def enable_disable_widgets(self, status):
    "Enable or disable the UI widgets"
    self.actionScan.set_sensitive(status)
    self.filePath.set_sensitive(status)
    self.txtVolumeName.set_sensitive(status)
    self.txtVolumeDescription.set_sensitive(status)
    self.chkSkipGvfs.set_sensitive(status)

if __name__ == '__main__':
  plugins.load_plugins()
  connection = sqlbackend.SqlBackEnd(preferences.DATABASE)
  ppid = len(sys.argv) > 1 and int(sys.argv[1]) or 0
  ui = ScanVolume(connection, ppid)
  plugins.signal_proxy('load')
  plugins.signal_proxy('on_uiready', argc=2, args=(ui, connection))
  ui.run()
  plugins.signal_proxy('on_terminate')
